"""强制关闭线程的脚本

ctypes 是Python的外部函数库。 -- ctypes主要还是用于调用dll和so里面的函数
    它提供了与 C语言兼容的数据类型，并允许调用 DLL 或共享库中的函数。
    可使用该模块以纯 Python 形式对这些库进行封装。
    -- https://blog.csdn.net/Qwertyuiop2016/article/details/125841653


inspect模块也被称为 检查现场对象。这里的重点在于“现场”二字，也就是当前运行的状态。
inspect模块提供了一些函数来了解现场对象，包括 模块、类、实例、函数和方法。
inspect函数主要用于以下四个方面
　　对是否是模块、框架、函数进行类型检查
　　获取源码
　　获取类或者函数的参数信息
　　解析堆栈
-- https://blog.csdn.net/NeverLate_gogogo/article/details/107752428?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168428444416800226583601%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168428444416800226583601&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-107752428-null-null.142^v87^control,239^v2^insert_chatgpt&utm_term=inspect&spm=1018.2226.3001.4187


"""
import ctypes
import inspect


def _async_raise(tid, exc_type):
    """
        在同步线程中通知其它线程,该线程中的异常已经完全运行。
    """
    # 变为C的数据类型
    # Python：int ctypes：c_long C:long
    tid = ctypes.c_long(tid)
    # 如果 exc_type 不为类
    if not inspect.isclass(exc_type):
        exc_type = type(exc_type)

    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exc_type))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")


# 强制关闭线程的方法
def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)
